package com.vmock.biz.client;

import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.w3c.dom.Document;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

/**
 * 模拟webservice的请求
 *
 * @author taofucheng
 * @date 2024/3/26
 */
@Slf4j
public class WebServiceClient {
    @Test
    public void requestWs() {
        String result = callServiceHP("http://localhost/vmock/example", "");
        System.out.println("响应的结果：" + result);
    }

    @Test
    public void requestWsEasy() throws Exception {
        String mobel = "18999170629";

        String xml = " <ns:reqt  xmlns:ns=\"http://esb.xjrccb.com/9900200001\">" +
                " <ns:svcHead>" +
                " <ns:SvcId>9900200001</ns:SvcId>" +
                " <ns:OptId>01</ns:OptId>" +
                " <ns:VerNo>1.0</ns:VerNo>" +
                " <ns:CsmId>sheji</ns:CsmId>" +
                " <ns:CsmTms>2008-09-29T01:49:45</ns:CsmTms>" +
                " <ns:CsmSeqNo>123</ns:CsmSeqNo>" +
                " </ns:svcHead>" +
                " <ns:extHead/>" +
                " <ns:appHead>" +
                " <ns:BsnNo></ns:BsnNo>" +
                " <ns:ReqBrcNo></ns:ReqBrcNo>" +
                " <ns:AuthNo></ns:AuthNo>" +
                " <ns:BpkSendTms></ns:BpkSendTms>" +
                " </ns:appHead>" +
                " <ns:appBody>" +
                " <ns:MblNo>" + mobel + "</ns:MblNo>" +
                " <ns:SmsCott></ns:SmsCott>" +
                " <ns:OpenCardBrc>string</ns:OpenCardBrc>" +
                " </ns:appBody>" +
                " </ns:reqt>";

        String respmsg = sendXml(xml, "example");
        System.out.print(respmsg);
    }

    public static String sendXml(String xml, String svcId)
            throws Exception {

        byte[] buf = xml.getBytes("utf-8");
        InputStream in = new ByteArrayInputStream(buf);

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        Document doc = factory.newDocumentBuilder().parse(in);

        DOMSource requestMsg = new DOMSource(doc);

        String ns = "http://esb.xjrccb.com/vmock/" + svcId + "wsdl";

        QName serviceName = new QName(ns, "TradeService");
        QName portName = new QName(ns, "TradePort");
        Service service = Service.create(serviceName);

        String URL = "http://localhost/vmock/" + svcId;

        service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, URL);
        Dispatch dispatch = service.createDispatch(portName, Source.class,
                Service.Mode.PAYLOAD);

        Source responseMsg = (Source) dispatch.invoke(requestMsg);

        TransformerFactory transFactory = TransformerFactory.newInstance();
        Transformer transformer = transFactory.newTransformer();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        StreamResult result = new StreamResult();
        result.setOutputStream(baos);

        transformer.transform(responseMsg, result);

        return baos.toString("utf-8");
    }

    /**
     * http post 调用 WebService
     *
     * @param wsUrl
     * @param jsonStr
     * @return
     */
    public static String callServiceHP(String wsUrl, String jsonStr) {
        String xml = createSoapContent(jsonStr);
        String uploadFeeDetailJsonStr = postWs(wsUrl, xml);
        return uploadFeeDetailJsonStr;
    }

    /**
     * 根据拼接 xml 字符串
     *
     * @param jsonStr
     * @return
     */
    public static String createSoapContent(String jsonStr) {
        log.info("开始拼接请求报文");
        //开始拼接请求报文
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:zys=\"http://www.chenjy.com.cn/\">\n");
        stringBuilder.append("<soapenv:Header/>\n");
        stringBuilder.append("<soapenv:Body>\n");
        stringBuilder.append("<cjy:CallInterface>\n");
        stringBuilder.append("<cjy:msgHeader><![CDATA[\n");
        stringBuilder.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
        stringBuilder.append("<root>\n");
        stringBuilder.append("<serverName>getInfo</serverName>\n");
        stringBuilder.append("<format>xml</format>\n");
        stringBuilder.append("<callOperator>测试</callOperator>\n");
        stringBuilder.append("<certificate>AcsaoP21Lxw5KAoQu6SLs624bhGjwNL0DzxsQ9a7B/HbqNsPPcA==</certificate>\n");
        stringBuilder.append("</root>\n");
        stringBuilder.append("]]></cjy:msgHeader>\n");
        stringBuilder.append("<cjy:msgBody><![CDATA[\n");
        stringBuilder.append(jsonStr + "\n");
        stringBuilder.append("]]></cjy:msgBody>\n");
        stringBuilder.append("</cjy:CallInterface>\n");
        stringBuilder.append("</soapenv:Body>\n");
        stringBuilder.append("</soapenv:Envelope>");
        log.info("拼接后的参数" + stringBuilder.toString());
        return stringBuilder.toString();
    }

    /**
     * 调用 webService
     *
     * @param url
     * @param xml
     * @return
     */
    public static String postWs(String url, String xml) {
        HttpResponse resp = HttpRequest.post(url).connectionTimeout(60000).timeout(60000)
                .contentType("application/xml", StandardCharsets.UTF_8.toString())
                .header("SOAPAction", "")
                .bodyText(xml, "application/xml", "utf-8")
                .charset(StandardCharsets.UTF_8.toString()).trustAllCerts(true)
                .send();
        resp.charset(StandardCharsets.UTF_8.toString());
        return resp.bodyText();
    }
}
